import { RESULT } from "./constance";
import {
  isMultipleOf3and5,
  isMultipleOf3and5and7,
  isMultipleOf3and7,
  isMultipleOf5and7,
  isNotMultipleOf3and5and7,
} from "./helpers/rule_3";
import {
  isJustMultipleOf3,
  isJustMultipleOf5,
  isJustMultipleOf7,
} from "./helpers/rule_2";
import {
  isContain3and5,
  isContain3and5and7,
  isContain3and7,
  isContain5and7,
  isJustContain3,
  isJustContain5,
  isJustContain7,
  isNotContain3and5and7,
} from "./helpers/rule_4";

export type FizzBuzzType = number | RESULT;

const fizzBuzzConverter = (number: number): FizzBuzzType => {
  if (number <= 0) return number;

  else if (isNotMultipleOf3and5and7(number)) {
    if (isJustContain3(number) || isContain3and7(number)) return RESULT.FIZZ;
    if (
      isNotContain3and5and7(number) ||
      isContain3and5(number) ||
      isJustContain5(number) ||
      isJustContain7(number) ||
      isContain5and7(number) ||
      isContain3and5and7(number)
    )
      return number;
  }

  else if (isJustMultipleOf3(number)) {
    if (
      isNotContain3and5and7(number) ||
      isJustContain3(number) ||
      isContain3and7(number) ||
      isJustContain7(number) ||
      isContain5and7(number) ||
      isContain3and5and7(number)
    ) {
      return RESULT.FIZZ;
    }
    if (isContain3and5(number) || isJustContain5(number)) return number;
  }

  else if (isJustMultipleOf5(number)) {
    if (
      isNotContain3and5and7(number) ||
      isContain3and5(number) ||
      isJustContain5(number)
    )
      return RESULT.BUZZ;

    if (isJustContain3(number) || isContain3and7(number)) return RESULT.FIZZ;
    if (
      isJustContain7(number) ||
      isContain5and7(number) ||
      isContain3and5and7(number)
    )
      return number;
  }

  else if (isJustMultipleOf7(number)) {
    if (
      isNotContain3and5and7(number) ||
      isContain3and5(number) ||
      isJustContain5(number) ||
      isJustContain7(number) ||
      isContain5and7(number) ||
      isContain3and5and7(number)
    )
      return RESULT.WHIZZ;

    if (isJustContain3(number) || isContain3and7(number)) return RESULT.FIZZ;
  }

  else if (isMultipleOf3and5and7(number)) {
    if (isNotContain3and5and7(number)) return RESULT.FIZZ_BUZZ_WHIZZ;
    if (isContain3and5(number) || isJustContain5(number))
      return RESULT.BUZZ_WHIZZ;
    if (
      isJustContain7(number) ||
      isContain5and7(number) ||
      isContain3and5and7(number)
    )
      return RESULT.FIZZ_WHIZZ;
    if (isJustContain3(number) || isContain3and7(number)) return RESULT.FIZZ;
  }

  else if (isMultipleOf3and5(number)) {
    if (isNotContain3and5and7(number)) return RESULT.FIZZ_BUZZ;
    if (isContain3and5(number) || isJustContain5(number)) return RESULT.BUZZ;
    if (
      isJustContain3(number) ||
      isJustContain7(number) ||
      isContain3and7(number) ||
      isContain5and7(number) ||
      isContain3and5and7(number)
    )
      return RESULT.FIZZ;
  }

  else if (isMultipleOf3and7(number)) {
    if (
      isNotContain3and5and7(number) ||
      isJustContain7(number) ||
      isContain5and7(number) ||
      isContain3and5and7(number)
    )
      return RESULT.FIZZ_WHIZZ;
    if (isContain3and5(number) || isJustContain5(number)) return RESULT.WHIZZ;
    if (isJustContain3(number) || isContain3and7(number)) return RESULT.FIZZ;
  }

  else if (isMultipleOf5and7(number)) {
    if (
      isNotContain3and5and7(number) ||
      isContain3and5(number) ||
      isJustContain5(number)
    )
      return RESULT.BUZZ_WHIZZ;
    if (
      isJustContain7(number) ||
      isContain5and7(number) ||
      isContain3and5and7(number)
    )
      return RESULT.WHIZZ;
    if (isJustContain3(number) || isContain3and7(number)) return RESULT.FIZZ;
  }

  return number;
};

export default fizzBuzzConverter;
